<template>
  <BackCommonBreadcrumb>
    <span class="btn search" @click="search">查询</span>
    <span class="btn reset" @click="reset">重置</span>
    <span class="btn add" @click="add">新增</span>
  </BackCommonBreadcrumb>
  <BackSearchForm :model="data.queryParams">
    <el-form-item label="角色名称">
      <el-input v-model="data.queryParams.name" clearable />
    </el-form-item>
  </BackSearchForm>
  <BackSimpleTable ref="simpleTable" :_configs="configs" :_data="data.dataList" :_total="data.total" @_load="loadTableData">
    <template #opt>
      <el-table-column v-slot="{ row }" prop="opt" label="操作" width="200">
        <span class="link edit" @click="edit(row)">编辑</span>
        <span class="link edit" @click="del(row)">删除</span>
      </el-table-column>
    </template>
  </BackSimpleTable>
  <BackSimpleDialog v-model="roleForm.dialogShow" :close-on-click-modal="false" :destroy-on-close="true" :close="cancel" width="600px">
    <template #header><span>{{ roleForm.dialogTitle }}</span></template>
    <template #default>
      <el-form
          ref="elRoleForm"
          label-position="right"
          label-width="100px"
          :rules="addRoleFormRules"
          :model="roleForm.formParams"
      >
        <el-form-item label="菜单名称" prop="name" required>
          <el-input v-model="roleForm.formParams.name" />
        </el-form-item>
        <el-form-item label="备注" prop="remark">
          <el-input v-model="roleForm.formParams.remark" />
        </el-form-item>
        <el-form-item label="关联菜单">
          <el-tree
              ref="roleMenuTree"
              class="menu_tree"
              :data="menuData"
              :props="defaultProps"
              node-key="id"
              accordion
              show-checkbox
              :default-checked-keys="defaultCheckMenuIds"
              @check-change="handleNodeCheck"
          />
        </el-form-item>
      </el-form>
    </template>
    <template #footer>
      <span class="btn cancel" @click="cancel(elRoleForm)">取消</span>
      <span class="btn confirm" @click="confirm(elRoleForm)">确认</span>
    </template>
  </BackSimpleDialog>
</template>

<script lang="ts" setup>
import type { FormInstance, FormRules } from "element-plus"
import { clearObjectFields } from "@/utils/helpers"

const { proxy }: any = getCurrentInstance()

const simpleTable = ref()
const roleMenuTree = ref()

const data = reactive({
  queryParams: {
    name: void 0
  },
  total: 0,
  dataList: []
})

const configs = [
  {
    prop: 'name',
    label: '角色名称'
  },
  {
    prop: 'remark',
    label: '备注'
  }
]

const search = () => {
  simpleTable.value._init()
}
const reset = () => {
  data.queryParams.name = void 0
}

const defaultProps = {
  children: 'children',
  label: 'name'
}

const defaultCheckMenuIds = ref<any>([])

const handleNodeCheck = async (node: any) => {
  if (!node) return
  if (roleMenuTree) {
    roleForm.formParams.menuIdList = roleMenuTree.value.getCheckedKeys() || []
  }
}

const menuData = ref<any>([])

const elRoleForm = ref()

const roleForm = reactive({
  dialogShow: false,
  dialogTitle: '',
  formParams: {
    id: void 0,
    name: void 0,
    remark: void 0,
    menuIdList: []
  }
})

const addRoleFormRules = reactive<FormRules>({
  name: [
    { required: true, message: '请输入角色名称！', trigger: '' }
  ]
})

const resetForm = () => {
  clearObjectFields(roleForm.formParams)
}

const add = () => {
  resetForm()
  defaultCheckMenuIds.value = []
  roleForm.dialogTitle = '新增角色'
  roleForm.dialogShow = true
}

const edit = (row: any) => {
  resetForm()
  roleForm.formParams.id = row.id
  roleForm.formParams.name = row.name
  roleForm.formParams.remark = row.remark
  roleForm.dialogTitle = '编辑角色'
  proxy.$API.systemApi.queryRoleMenu({ roleId: row.id, column: 'id' }).then((res: any) => {
    roleForm.formParams.menuIdList = res || []
    defaultCheckMenuIds.value = res || []
    roleForm.dialogShow = true
  })
}

const confirm = async (formEl: FormInstance | undefined) => {
  if (!formEl) return
  if (roleForm.formParams.id) {
    await formEl.validate((valid, fields) => {
      if (valid) {
        let { id, name, remark, menuIdList } = roleForm.formParams
        proxy.$API.systemApi.updateSysRole({ id, name, remark, menuIdList }).then((res: any) => {
          if (res.code && res.code === 10000) {
            ElMessage.success('编辑成功！')
            roleForm.dialogShow = false
            search()
          } else {
            ElMessage.error(res.msg || '编辑失败！')
          }
        })
      }
    })
  } else {
    await formEl.validate((valid, fields) => {
      if (valid) {
        let { name, remark, menuIdList } = roleForm.formParams
        proxy.$API.systemApi.insertSysRole({ name, remark, menuIdList }).then((res: any) => {
          if (res.code && res.code === 10000) {
            ElMessage.success('添加成功！')
            roleForm.dialogShow = false
            search()
          } else {
            ElMessage.error(res.msg || '添加失败！')
          }
        })
      }
    })
  }
}

const cancel = async (formEl: FormInstance | undefined) => {
  if (formEl) {
    formEl.resetFields()
  }
  roleForm.dialogShow = false
}

const del = (row: any) => {
  ElMessageBox.confirm('确认删除该角色？', '通知', {
    confirmButtonText: '确认',
    cancelButtonText: '取消'
  }).then(() => {
    proxy.$API.systemApi.deleteSysRole({ id: row.id }).then((res: any) => {
      if (res.code && res.code === 10000) {
        ElMessage.success('删除成功！')
        search()
      } else {
        ElMessage.error(res.msg || '删除失败！')
      }
    })
  }).catch(() => {})
}

const loadTableData = (pageNum?: number, pageSize?: number) => {
  proxy.$API.systemApi.querySysRole({ ...data.queryParams, pageNum, pageSize }).then((res: any) => {
    data.dataList = res.records ?? []
    data.total = res.total ?? 0
  })
}

const loadMenuData = () => {
  const topMenu = {
    id : 0,
    parentId: void 0,
    level: 0,
    name: '系统菜单',
    mark: 'systemMenu',
    children: void 0
  }
  proxy.$API.systemApi.queryMenuTree({}).then((res: any) => {
    topMenu.children = res ?? []
    menuData.value = [ topMenu ]
  })
}

onMounted(() => {
  loadMenuData()
})
</script>

<style lang="less" scoped>
.menu_tree {
  width: 100%;
}
</style>
